package com.dragon.logical.service.contract.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.repository.entity.Rejected;
import com.dragon.repository.entity.RejectedProduct;
import com.dragon.repository.entity.Repair;
import com.dragon.repository.entity.RepairProduct;
import com.dragon.repository.mapper.RejectedMapper;
import com.dragon.repository.mapper.RejectedProductMapper;
import com.dragon.repository.mapper.RepairMapper;
import com.dragon.logical.service.contract.IRepairService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.repository.mapper.RepairProductMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * <p>
 * 维修单据表 服务实现类
 * </p>
 *
 * @author sy
 * @since 2023-12-05
 */
@Service
public class RepairServiceImpl extends ServiceImpl<RepairMapper, Repair> implements IRepairService {

    @Autowired
    RepairMapper mapper;

    @Autowired
    RepairProductMapper productMapper;

    @Autowired
    RejectedProductMapper rejectedProductMapper;
    @Autowired
    RejectedMapper rejectedMapper;



    @Override
    public Page<Repair> selectListPage(String name, Integer status, Integer page, Integer limit){

        Page<Repair> page1 = new Page<>(page,limit);

        QueryWrapper queryWrapper = new QueryWrapper();

        queryWrapper
                .like(StrUtil.isNotBlank(name),"dc.name",name)
                .eq(status!=null,"dr.status",status);

        Page<Repair> repairPage = mapper.selectListPage(page1,queryWrapper);

        return repairPage;
    }



    @Override
    public Repair selectDetailById(Integer id){
        // 维修主表
        Repair repair = mapper.selectDetailById(id);
        if(repair == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        // 维修产品表
        List<RepairProduct> repairProduct = productMapper.selectListByMainId(id);
        repair.setRepairProducts(repairProduct);

        return repair;
    }




    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void addRepair(Repair repair){
        // 添加到指定的维修表单中
        repair.setCreateTime(DateUtil.date());
        mapper.insert(repair);
        repair.getRepairProducts().forEach(e->{
            e.setRepairId(repair.getId());
            productMapper.insert(e);

            RejectedProduct rejectedProduct = rejectedProductMapper.selectOne(
                    new LambdaQueryWrapper<RejectedProduct>().eq(RejectedProduct::getRejectedId,repair.getRejectId())
                            .eq(RejectedProduct::getProductId,e.getProductId())
            );
            Integer num = rejectedProduct.getProcessingNum() + e.getRejectNum();
            // 处理中的数量
            rejectedProduct.setProcessingNum(num);
        });
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void delete(Integer id){
        Repair repair = mapper.selectById(id);
        if(repair == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        mapper.deleteById(repair);
        // 删除退货表中对应的处理数量
        List<RepairProduct> repairProducts = productMapper.selectList(new LambdaQueryWrapper<RepairProduct>().eq(RepairProduct::getRepairId,id));
        repairProducts.forEach(repairProduct -> {
            RejectedProduct rejectedProduct = rejectedProductMapper.selectOne(
                    new LambdaQueryWrapper<RejectedProduct>().eq(RejectedProduct::getRejectedId,repair.getRejectId())
                            .eq(RejectedProduct::getProductId,repairProduct.getProductId())
            );
            Integer num = rejectedProduct.getHandleNum() - repairProduct.getRejectNum();
            // 处理中的数量
            rejectedProduct.setHandleNum(num);
        });
        productMapper.delete(new LambdaQueryWrapper<RepairProduct>().eq(RepairProduct::getRepairId,id));
    }


    @Override
    public void updateStatus(Integer id, Integer status){
        Repair repair = mapper.selectById(id);
        if(repair == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        repair.setStatus(status);
        repair.setUpdateTime(DateUtil.date());

        Rejected rejected = rejectedMapper.selectById(repair.getRejectId());
        AtomicReference<Boolean> flag = new AtomicReference<>(true);
        List<RepairProduct> repairProducts = productMapper.selectList(new QueryWrapper<RepairProduct>().lambda()
                .eq(RepairProduct::getRepairId, id));
        repairProducts.forEach(repairProduct -> {
            repairProduct.setRejectRealityNum(repairProduct.getRejectNum());
            repairProduct.setUpdateTime(DateUtil.date());
            productMapper.updateById(repairProduct);
            RejectedProduct rejectedProduct = rejectedProductMapper.selectOne(
                    new LambdaQueryWrapper<RejectedProduct>()
                            .eq(RejectedProduct::getRejectedId, repair.getRejectId())
                            .eq(RejectedProduct::getProductId, repairProduct.getProductId())
            );
            Integer num  = rejectedProduct.getHandleNum() + repairProduct.getRejectRealityNum();
            rejectedProduct.setHandleNum(num);
            rejectedProduct.setUpdateTime(DateUtil.date());
            rejectedProductMapper.updateById(rejectedProduct);
            if (rejectedProduct.getRecededNum() < num){
                flag.set(false);
            }
        });
        if (flag.get()){
            rejected.setRejectedState(1);
            rejectedMapper.updateById(rejected);
        }

        mapper.updateById(repair);
    }



}
